package org.xstudio.flutter_wifi_connector

import android.content.Context
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager
import android.net.wifi.WifiNetworkSuggestion
import android.os.Build
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

/** FlutterWifiConnectorPlugin */
class FlutterWifiConnectorPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel
  private lateinit var context: Context

  override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_wifi_connector")
    channel.setMethodCallHandler(this)
    context = flutterPluginBinding.applicationContext
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    when (call.method) {
      "getPlatformVersion" -> {
        result.success("Android ${android.os.Build.VERSION.RELEASE}")
      }
      "connectToWifi" -> {
        val ssid = call.argument<String>("ssid")
        val password = call.argument<String>("password")
        
        if (ssid == null || password == null) {
          result.success(mapOf(
            "success" to false,
            "message" to "SSID and password are required"
          ))
          return
        }
        
        connectToWifi(ssid, password, result)
      }
      else -> {
        result.notImplemented()
      }
    }
  }

  private fun connectToWifi(ssid: String, password: String, result: Result) {
    try {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Android 10 and above - use WifiNetworkSuggestion for permanent configuration
        addNetworkSuggestion(ssid, password, result)
      } else {
        // Android 9 and below - use WifiManager
        connectToWifiAndroid9AndBelow(ssid, password, result)
      }
    } catch (e: Exception) {
      result.success(mapOf(
        "success" to false,
        "message" to "Error connecting to WiFi: ${e.message}"
      ))
    }
  }

  @Suppress("DEPRECATION")
  private fun connectToWifiAndroid9AndBelow(ssid: String, password: String, result: Result) {
    val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
    
    if (!wifiManager.isWifiEnabled) {
      // Try to enable WiFi
      wifiManager.isWifiEnabled = true
      Thread.sleep(1000) // Wait for WiFi to enable
    }
    
    val wifiConfig = WifiConfiguration()
    wifiConfig.SSID = String.format("\"%s\"", ssid)
    wifiConfig.preSharedKey = String.format("\"%s\"", password)
    
    // Remove existing configurations for this SSID
    val list = wifiManager.configuredNetworks
    if (list != null) {
      for (config in list) {
        if (config.SSID != null && config.SSID == wifiConfig.SSID) {
          wifiManager.removeNetwork(config.networkId)
          wifiManager.saveConfiguration()
        }
      }
    }
    
    // Add and enable the network
    val networkId = wifiManager.addNetwork(wifiConfig)
    
    if (networkId == -1) {
      result.success(mapOf(
        "success" to false,
        "message" to "Failed to add network configuration"
      ))
      return
    }
    
    wifiManager.disconnect()
    val enabled = wifiManager.enableNetwork(networkId, true)
    val reconnected = wifiManager.reconnect()
    
    if (enabled && reconnected) {
      result.success(mapOf(
        "success" to true,
        "message" to "Successfully initiated connection to $ssid"
      ))
    } else {
      result.success(mapOf(
        "success" to false,
        "message" to "Failed to connect to $ssid"
      ))
    }
  }

  private fun addNetworkSuggestion(ssid: String, password: String, result: Result) {
    try {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Android 10 and above - use WifiNetworkSuggestion
        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        
        // Create network suggestion
        val suggestion = WifiNetworkSuggestion.Builder()
          .setSsid(ssid)
          .setWpa2Passphrase(password)
          .setIsAppInteractionRequired(false) // Don't require user approval for connection
          .setPriority(1) // Higher priority
          .build()
        
        val suggestionsList = listOf(suggestion)
        
        // Remove previous suggestions first (optional, to avoid duplicates)
        wifiManager.removeNetworkSuggestions(emptyList())
        
        // Add the network suggestion
        val status = wifiManager.addNetworkSuggestions(suggestionsList)
        
        when (status) {
          WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS -> {
            result.success(mapOf(
              "success" to true,
              "message" to "Successfully connected to $ssid. Network saved to device."
            ))
          }
          WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE -> {
            result.success(mapOf(
              "success" to true,
              "message" to "Network $ssid is already saved."
            ))
          }
          WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED -> {
            result.success(mapOf(
              "success" to false,
              "message" to "App is not allowed to add network suggestions. Please enable in WiFi settings."
            ))
          }
          else -> {
            result.success(mapOf(
              "success" to false,
              "message" to "Failed to add network. Status code: $status"
            ))
          }
        }
      } else {
        // Android 9 and below - use WifiManager (same as connectToWifi)
        connectToWifiAndroid9AndBelow(ssid, password, result)
      }
    } catch (e: Exception) {
      result.success(mapOf(
        "success" to false,
        "message" to "Error adding network: ${e.message}"
      ))
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}
